import java.util.ArrayList;

/**
 * @author Meraner Marcel
 * 
 * Klasse die das Verhalten an die and die Aktionen bindet bzw steuert.
 * Tutorial: http://www.lejos.org/nxt/nxj/tutorial/Behaviors/BehaviorProgramming.htm      
 */
public class Arbitrator {

	private final int HAS_NO_BEHAVIOR = -1;

	// Verhalten
	private ArrayList<BehaviorAgent> behaviors;
	// Verhalten mit der h�chsten Prio wird gespeichert
	private int highestPriorityOfBehavor = HAS_NO_BEHAVIOR;
	// aktuelles Verhalten
	private int activeBehavior = HAS_NO_BEHAVIOR;
	private BehaviorController behavCtrl;

	public Arbitrator(ArrayList<BehaviorAgent> behaviors) {
		this.behaviors = behaviors;
		behavCtrl = new BehaviorController();
	}

	
	public void run() {
		behavCtrl.start();
		while (highestPriorityOfBehavor == HAS_NO_BEHAVIOR) {
			Thread.yield();
		}

		while (true) {
			synchronized (behavCtrl) {
				if (highestPriorityOfBehavor != HAS_NO_BEHAVIOR) {
					activeBehavior = highestPriorityOfBehavor;
				}
			}
			
			if (activeBehavior != HAS_NO_BEHAVIOR) {
				// _highestPrioirty kann auch keines sein
				behaviors.get(activeBehavior).action();
				activeBehavior = HAS_NO_BEHAVIOR;
				// kein Aktives verhalten zurzeit
			}
			Thread.yield();
		}
	}

	/**
	 * @author Meraner Marcel
	 * Klasse findet h�chste Prio welche die Kontrolle will
	 * Tutorial: http://www.lejos.org/nxt/nxj/tutorial/Behaviors/BehaviorProgramming.htm 
	 */
	private class BehaviorController extends Thread {
		int amountOnBehaviors = behaviors.size() - 1;

		public void run() {
			while (true) {
			
				// h�chste Priorit�t finden welche die Kontrolle haben will
				synchronized (this) {
					highestPriorityOfBehavor = HAS_NO_BEHAVIOR;
					for (int curBehavior = amountOnBehaviors; curBehavior >= 0; curBehavior--) {
						if (behaviors.get(curBehavior).takeControl()) {
							highestPriorityOfBehavor = curBehavior;
							break;
						}
					}
				}
				Thread.yield();
			}
		}
	}

}
